
//饿汉式
class Singleton{
    private static Singleton instance = new Singleton();
    public static Singleton getInstance() {
        return instance;
    }
    private Singleton(){

    }
}
//懒汉模式
class SingletonLazy{
    private volatile static SingletonLazy instance = null;
    public static SingletonLazy getInstance(){
        if(instance != null){
            synchronized(SingletonLazy.class){
                if(instance != null){
                    instance = new SingletonLazy();
                }
            }
        }
        return instance;
    }
}


/*class SingletonLazy{
    //懒汉式
    private static SingletonLazy instance = null;
    public static SingletonLazy getInstance(){
        if(instance != null){//判断是否要加锁，因为加锁需要大量开销，所以开始的时候判断一次就够了
            synchronized(SingletonLazy.class){
                *//**
                 * 判断是否实例，由于加锁开销很大，导致第一次if与第二次if相差时间甚远；
                 * 所以第二次if的时候，instance，就不知道有没有被其他线程实例，不知道是否还是null了
                 *//*
                if(instance != null){
                    instance = new SingletonLazy();
                }
            }
        }
        return instance;
    }
    //这重写构造方法是为了防止类外再new实例
    private SingletonLazy(){

    }
}
*/
public class Test {
    public static void main(String[] args){
        Singleton instance = Singleton.getInstance();
    }
    public static void main1(String[] args){
        Object o1 = new Object();
        Object o2 = new Object();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized(o2){
                    for(int i = 0; i < 10; i++){
                        try {
                            o2.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("c");
                        synchronized(o1){
                            o1.notify();
                        }
                    }
                }

            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized(o1){
                    for(int i = 0; i < 10; i++){
                        try {
                            o1.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.print("b");
                        synchronized(o2){
                            o2.notify();
                        }
                    }
                }

            }
        });
        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized(o1){
                    for(int i = 0; i < 10; i++){
                        System.out.print("a");
                        o1.notify();
                        try {
                            o1.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        t1.start();
        t2.start();
        t3.start();
    }
}
